﻿using Commons.ASPNETCore;
using IdentityService.Domain;
using IdentityService.Domain.Entities;
using Commons.DomainBase;
using Microsoft.AspNetCore.Identity;
using Zack.Commons;
using Kogel.Repository;
using Commons.Infrastructure;
using Kogel.Repository.Interfaces;
using Kogel.Dapper.Extension;

namespace IdentityService.Infrastructure
{
    public class IdRepository : IIdRepository
    {
        private readonly IRepository<User> userRepository;
        private readonly IBaseRepository<Role> roleRepository;
        private readonly IBaseRepository<UserRole> userRoleRepository;
        private readonly IUserManager userManager;
        public IdRepository(IRepository<User>userRepository , IUserManager userManager)
        {
            this.userRepository = userRepository;      
            this.userManager=userManager;
            this.roleRepository = userRepository.QuerySet<Role>().GetRepository();
            this.userRoleRepository = userRepository.QuerySet<UserRole>().GetRepository(); ;
        }

        public async Task<bool> CreateAsync(User user)
        {
            
            return await userManager.CreateAsync(user);
        }

        public IEnumerable<User> FindAllUsers(long userId)
        {
            return userRepository.QuerySet().Where(x => x.CreateUserId == userId && x.IsDeleted == 0).OrderByDescing(x=>x.CreationTime).ToIEnumerable();
        }


        public async Task<User?> FindByIdAsync(long userId)
        {
            return await userManager.FindByIdAsync(userId);
        }

        public async Task<User?> FindByNameAsync(string userName)
        {
            return await userManager.FindByNameAsync(userName);
        }

        public Task<User?> FindByPhoneNumberAsync(string phoneNum)
        {
            throw new NotImplementedException();
        }

        public async Task<bool> RoleExistsAsync(string roleName)
        {
            var role= await roleRepository.QueryAsync(x=>x.Name==roleName);
            return role != null;
        }

        public async Task<bool> AddToRoleAsync(User user, string roleName)
        {
              //todo 有必要每次添加都去审核吗
            if(!await RoleExistsAsync(roleName))
            {
                Role role = new() { Name = roleName };
                var result = await roleRepository.CommandSet().InsertIdentityAsync(role);
          //      if (result > 0)
           //     {
             //       return false;
            //   }
            }
            //查询角色是否已存在
            var userRole= await userRoleRepository.QuerySet().Where(x=>x.UserID==user.Id&&x.RoleName==roleName).GetAsync(); 
            if (userRole != null)
            {
                return false;
            }
            //添加角色
            var resul =await userRoleRepository.InsertIdentityAsync(UserRole.Create(user, roleName));
            if (resul > 0)
            {
                return true;
            }
            return false;
        }
        
        public async Task<IList<string>> GetRolesAsync(User user)
        {
            var list = await userRoleRepository.QueryAsync(x => x.UserID == user.Id);
            return list.Select(x=>x.RoleName).ToList();
        }

        public Task<User?> FindBySinaOAuthAsync(string SinaId)
        {
            throw new NotImplementedException();
        }

        public  (bool,int) CheckForSignIn(User user, string password, bool lockoutOnFailure)
        {

           var (result, errorCount) = userManager.IsLockedOut(user);
                if (result)
                {
                    return (false,errorCount);
                }

            result =  userManager.CheckPassword(user, password);

            if (!result)
            {
                if (lockoutOnFailure)
                {
                    return userManager.AccessFailed(user);
                }
                return (false,0);
            }
            return (true,0);
        }

        public Task<bool> CheckForSignInAsync(User user, string password, bool lockoutOnFailure)
        {
            throw new NotImplementedException();
        }


        public async Task<(bool, User?,string)> AddTeacherAsync(User user)
        {
            var result = await CreateAsync(user);
            if (!result)
            {
                return (false, null, "新增失败");
            }
            result = await AddToRoleAsync(user, "Teacher");
            if (!result)
            {
                return (false, null, "权限新增失败");
            }
            return (true, user, "新增成功");
        }


        public async Task<(string, User?, string? password)> AddAdminUserAsync(string userName, string phoneNum)
        {
            if (await FindByNameAsync(userName) != null)
            {
                return (($"已经存在用户名{userName}"), null, null);
            }
            if (await FindByPhoneNumberAsync(phoneNum) != null)
            {
                return (($"已经存在手机号{phoneNum}"), null, null);
            }

            string password = "123456";
            User user = User.Create( userName, password);
          //  user.PhoneNumber = phoneNum;
          //  user.PhoneNumberConfirmed = true;
        //    string password = GeneratePassword();
            var result = await CreateAsync(user);
            if (!result)
            {
                return ("新增失败", null, null);
            }
            result = await AddToRoleAsync(user, "Admin");
            if (!result)
            {
                return ("权限新增失败", null, null);
            }
            return ("新增成功", user, password);
        }

        public async Task<bool> ChangePasswordAsync(long userId, string password)
        {
            if (password.Length < 6)
            {
                IdentityError err = new IdentityError();
                err.Code = "Password Invalid";
                err.Description = "密码长度不能少于6";
                return false;
            }
            var user = await userManager.FindByIdAsync(userId);
           // var token = await userManager.GeneratePasswordResetTokenAsync(user);
            //var resetPwdResult = await userManager.ResetPasswordAsync(user, token, password);
            return true;
        }

        public async Task<(bool, User?, string? password)> ResetPasswordAsync(long id)
        {
            var user = await FindByIdAsync(id);
            if (user == null)
            {
                return (false, null, null);
            }
         //   string password = GeneratePassword();
         //   string token = await userManager.GeneratePasswordResetTokenAsync(user);
         //   var result = await userManager.ResetPasswordAsync(user, token, password);
        //    if (!result.Succeeded)
        //    {
        //        return (result, null, null);
        //    }
            return (true, user, null);
        }

        public async Task<(bool, User?, string? msg)> AddUserAsync(User user, string RoleName)
        {
            var result = await CreateAsync(user);
            if (!result)
            {
                return (false, null, "新增失败");
            }
            result = await AddToRoleAsync(user, RoleName);
            if (!result)
            {
                return (false, null, "权限新增失败");
            }
            return (true, user, "新增成功");
        }

        public PageList<User> FindAllUserPage(long userId,int pageIndex,int pageSize)
        {

            return userRepository.QueryPage(x => x.CreateUserId == userId && x.IsDeleted == 0, pageIndex, pageSize,x=>x.CreationTime);
        }
    }
}
